package com.cndw.kungfu.model.union;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.cndw.commons.util.BlankUtils;
import com.cndw.kungfu.comm.JXSpreadTask;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsConfig;
import com.cndw.kungfu.config.ConstantsIntKey;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.config.ConstantsRadio;
import com.cndw.kungfu.core.CacheCenter;
import com.cndw.kungfu.dao.UnionDao;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Title;
import com.cndw.kungfu.domain.Union;
import com.cndw.kungfu.domain.UnionAsset;
import com.cndw.kungfu.domain.UnionCashCow;
import com.cndw.kungfu.domain.UnionConfig;
import com.cndw.kungfu.domain.UnionMember;
import com.cndw.kungfu.domain.UnionSkillConfig;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.DataSerialize;
import com.cndw.kungfu.model.siege.domain.SiegeWar;
import com.cndw.kungfu.vo.UnionVO;

/**
 * 帮派管理服务
 * 
 * @author <a href="mailto:whz-work@163.com">汪洪州</a>
 * 
 * @since 1.0 Create on 2011-5-18
 */
@Service
public class UnionManager {

	@Resource
	private UnionDao unionDao;
	@Resource
	private CacheCenter cacheCenter;
	private static int currentAutoNumber = -1;

	private synchronized int getNextUnionId() {

		if (currentAutoNumber < 0) {
			int currentUnionId = 0;
			try {
				currentUnionId = unionDao.getMaxUnionId();
			} catch (NullPointerException e) {

			} catch (Exception e) {
				e.printStackTrace();
			}
			currentAutoNumber = (int) (currentUnionId / 1000);
		}
		currentAutoNumber++;

		return currentAutoNumber * 1000 + ConstantsConfig.getSysCgAutoNumberSuffix();
	}

	public List<UnionConfig> getAllUnionConfigFromDb() {
		try {
			return unionDao.getAllUnionConfig();
		} catch (Exception e) {
			return new ArrayList<UnionConfig>();
		}
	}

	public List<UnionSkillConfig> getAllUnionSkillConfig() {
		try {
			return unionDao.getAllUnionSkillConfig();
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<UnionSkillConfig>();
		}
	}

	public Union insertUnion(String unionName, long playerId, String playerName) {

		Union union = new Union();

		union.setId(getNextUnionId());

		union.setName(unionName);
		union.setPlayerId(playerId);
		union.setPlayerName(playerName);
		union.setLevel(1);
		union.setValidMode((short) 1);
		union.setAddTime(TimeProcesser.getUnixTime());

		try {

			unionDao.insertUnion(union);

			UnionCashCow cashCow = new UnionCashCow();
			cashCow.setUnionId(union.getId());
			unionDao.insertUnionCashCow(cashCow);

			return union;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public UnionCashCow getUnionCashCow(int unionId) {
		try {
			return unionDao.getUnionCashCow(unionId);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public void updateUnionCashCowReward(UnionCashCow cashCow) {
		try {
			unionDao.updateUnionCashCowReward(cashCow);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void updateUnionCashGrowValue(UnionCashCow cashCow) {
		try {
			unionDao.updateUnionCashGrowValue(cashCow);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public UnionMember insertUnionMemeber(int unionId, long playerId, int position) {
		
		UnionMember member = new UnionMember();
		member.setUnionId(unionId);
		member.setPlayerId(playerId);
		member.setPosition(position);
		member.setResource(0);
		member.setHissource(0);
		member.setAddTime(TimeProcesser.getUnixTime());

		increaseUnionMemberCount(1, unionId);

		try {
			unionDao.insertUnionMember(member);
			Context.getUnionServer().getUnionById(unionId).addMember(member);
			// addUnionTitle(unionId, playerId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return member;
	}

	public boolean checkUnionExist(String unionName) {
		try {
			return unionDao.checkUnionExist(unionName) != null;
		} catch (Exception e) {
			e.printStackTrace();
			return true;
		}
	}

	public Union getUnionById(int unionId) {
		try {
			return unionDao.getUnionById(unionId);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public List<UnionMember> getUnionMemberByUnionId(int unionId) {
		try {
			return unionDao.getUnionMemberByUnionId(unionId);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<UnionMember>();
		}
	}

	public void deleteUnion(int unionId) {

		try {
			unionDao.deleteUnion(unionId);
			Context.getDataServer().getUnionMap().remove(unionId);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void deleteAllUnionMember(int unionId) {
		try {
			unionDao.deleteAllUnionMember(unionId);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void updateUnionPlayerName(Union union) {
		try {
			unionDao.abdicate(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void abdicate(Union union, UnionMember accede, UnionMember abdicate) {
		try {
			unionDao.abdicateMember(abdicate);
			unionDao.abdicateMember(accede);
			unionDao.abdicate(union);
			addUnionTitle(abdicate.getPlayerId(), accede.getPlayerId());
			removeUnionTitle(abdicate.getPlayerId());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void updateMemberResource(UnionMember member) {
		try {
			unionDao.updateMemberResource(member);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void deleteUnionMember(UnionMember member) {
		try {
			unionDao.deleteUnionMember(member);
			decreaseMemberCount(1, member.getUnionId());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void increaseUnionMemberCount(int count, int unionId) {
		try {
			Union union = Context.getUnionServer().getUnionById(unionId);
			synchronized (union) {
				union.setMemberCount(union.getMemberCount() + 1);
				unionDao.increaseUnionMemberCount(count, unionId);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void decreaseMemberCount(int count, int unionId) {
		try {
			Union union = Context.getUnionServer().getUnionById(unionId);
			synchronized (union) {
				union.setMemberCount(union.getMemberCount() - 1);
				unionDao.decreaseMemberCount(count, unionId);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public UnionConfig getUnionConfigByLevel(int level) {
		return cacheCenter.getUnionConfigByLevel(level);
	}

	public UnionSkillConfig getUnionSkillConfig(String key) {
		return cacheCenter.getUnionSkillConfig(key);
	}

	public void upgradeUnionLevel(Union union) {
		try {
			unionDao.upgradeUnionLevel(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void upgradeUnionSkillLevel(Union union) {
		try {
			unionDao.upgradeUnionSkillLevel(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void upgradeTechLevel(Union union) {
		try {
			unionDao.upgradeTechLevel(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void addResource(Union union) {
		try {
			unionDao.addResource(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void publishNotice(Union union) {
		try {
			unionDao.publishNotice(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void settingUnion(Union union) {
		try {
			unionDao.settingUnion(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void settingMember(UnionMember member) {
		try {
			unionDao.settingMember(member);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void watering(UnionMember member) {
		try {
			unionDao.watering(member);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void updateUnionAsset(Union union) {
		try {
			unionDao.updateUnionAsset(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void updatePetLv(Union union) {
		try {
			unionDao.updatePetLv(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void updateUnionResAsset(Union union) {
		try {
			unionDao.updateUnionResAsset(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void updateUnion(Union union) {
		try {
			unionDao.updateUnion(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void updateUnionPrestige(Union union) {
		try {
			unionDao.updateUnionResource(union);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<UnionVO> getUnionList(long playerId, int offset, int limit, String search) {

		Player player = Context.getPlayerServer().getByPlayerId(playerId);
		Set<Integer> unionIds = player.getDataInfo().getApplyUnions();
		List<UnionVO> unionVOList = new ArrayList<UnionVO>();
		try {
			List<Union> unionList = unionDao.getUnionList(offset, limit, search);
			int ranking = offset + 1;
			for (int i = 0, j = unionList.size(); i < j; i++) {
				Union union = unionList.get(i);
				if (union.getId() != player.getUnionId()) {
					UnionVO unionVO = union.toUnionVO();
					unionVO.setRanking(ranking);

					if (!BlankUtils.isBlank(unionIds) && unionIds.contains(unionVO.getId())) {
						int timestamp = player.getDataInfo().getApplyUnion(unionVO.getId());
						if ((TimeProcesser.getUnixTime() - timestamp) > ConstantsModel.unionApplyTime) {
							player.getDataInfo().removeApplyUnion(unionVO.getId());
							unionVO.setApplyStatus(0);
						} else {
							unionVO.setApplyStatus(1);
						}
					} else {
						unionVO.setApplyStatus(0);
					}

					unionVOList.add(unionVO);
					ranking++;
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return unionVOList;
	}

	public int getUnionListCount(String search) {
		try {
			return unionDao.getUnionListCounnt(search);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public List<Union> getByUnionPetOrder() {
		try {
			return unionDao.getByUnionPetOrder();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public void addAssetLog(int unionId, long playerId, String playerName, int asset, int resource, int eventType) {
		try {
			if (asset == 0 && resource == 0) {
				return;
			}
			UnionAsset unionAsset = UnionAsset.getUnionAsset(unionId, playerId, playerName, asset, resource, eventType);

			unionDao.addUnionAsset(unionAsset);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<UnionAsset> getAddUnionAssets(int unionId) {
		try {
			return unionDao.getAddUnionAssets(unionId);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<UnionAsset>();
		}
	}

	public List<UnionAsset> getExpendUnionAssets(int unionId) {
		try {
			return unionDao.getExpendUnionAssets(unionId);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<UnionAsset>();
		}
	}

	public void updateCashCowReward(UnionMember member) {
		try {
			unionDao.updateCashCowReward(member);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void deleteUnionCashCow(int unionId) {
		try {
			unionDao.deleteUnionCashCow(unionId);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<Integer> getMaintainUnionIdsDB(int time) {
		try {
			return unionDao.getMaintainUnionIds(time);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<Integer>();
		}
	}

	public void dismissUnion(Union union, String title, String content) {

		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("unionId", 0);
		resultMap.put("flag", 0);
		resultMap.put("permission", 0);

		for (UnionMember member : union.getMembers()) {
			Player player = Context.getPlayerServer().getByPlayerId(member.getPlayerId());
			Context.getMessageServer().recordEvent(member.getPlayerId(), title, content, Constants.eventTypeNormal);
			Context.getTcpServer().broadcast(resultMap, ConstantsRadio.unionIdUpdateRadio, member.getPlayerId());
			setQuitCounts(player);
			SiegeWar.removePlayer(player.getPlayerId()); // 移除围城玩家
		}

		Map<Long, Integer> applyMap = DataSerialize.getInstance().getApplyMember().get(union.getId());
		if (!BlankUtils.isBlank(applyMap)) {
			for (Long playerId : applyMap.keySet()) {
				Player player = Context.getPlayerServer().getByPlayerId(playerId);
				player.getDataInfo().removeApplyUnion(union.getId());
			}
		}

		removeUnionTitle(union.getPlayerId());
		deleteUnion(union.getId());
		deleteAllUnionMember(union.getId());
		deleteUnionCashCow(union.getId());
	}

	/**
	 * 检查权限
	 * 
	 * @param playerId
	 *            当前玩家Id
	 * @param permession
	 *            帮派相关操作的权限
	 * @return 返回布尔值，true表示检查不到该权限，false表示拥有该权限
	 */
	public boolean checkPermission(long playerId, int permession) {
		UnionMember playerMember = Context.getUnionServer().getUnionByPlayerId(playerId).getMember(playerId);
		return playerMember == null || ((ConstantsConfig.getUnionJobsFlag()[playerMember.getPosition()] | playerMember.getFlag()) & permession) == 0;
	}

	/**
	 * 设置帮派退出和解散次数
	 * 
	 * @param player
	 */
	public void setQuitCounts(Player player) {
		if ((TimeProcesser.getUnixTime() - player.getDataInfo().intDataGet(ConstantsIntKey.QUnionTime)) < 86400) {
			if (player.getDataInfo().intDataGet(ConstantsIntKey.QUnionNums) < ConstantsModel.unionJoinCounts) {
				player.getDataInfo().intDataAlter(ConstantsIntKey.QUnionNums, 1);
			}
		} else {
			player.getDataInfo().intDataSet(ConstantsIntKey.QUnionNums, 1);
			player.getDataInfo().intDataSet(ConstantsIntKey.QUnionTime, TimeProcesser.getUnixTime());
		}
		player.setUnionId(0);
		player.clacProperties();
		player.commitSync();
		player.getDataInfo().commitSync();
	}
	
	public UnionMember setUnionIdAdd(Player player,int unionId,int position){
		clearApplyAndInvite(player);
		UnionMember unionMemeber = insertUnionMemeber(unionId, player.getPlayerId(), position);
		player.setUnionId(unionId);
		JXSpreadTask.complete(player, JXSpreadTask.applyUnion);
		return unionMemeber;
	}

	/**
	 * 检查24小时内退出帮派是否超过次数显示
	 * 
	 * @param player
	 * @return true 表示限制，false表示未限制
	 */
	public boolean checkQuitCountsLimit(Player player) {
		if ((TimeProcesser.getUnixTime() - player.getDataInfo().intDataGet(ConstantsIntKey.QUnionTime)) > 86400) {
			return false;
		} else {
			return player.getDataInfo().intDataGet(ConstantsIntKey.QUnionNums) >= ConstantsModel.unionJoinCounts;
		}
	}

	/**
	 * 检查帮派成员数是否达到限制
	 * 
	 * @param union
	 *            帮派对象
	 * @return 返回布尔值，true表示已经达到最大限制，false表示还未达到限制人数
	 */
	public boolean checkUnionMemberLimit(Union union) {
		UnionConfig unionConfig = getUnionConfigByLevel(union.getLevel());
		return union.getMembers().size() >= unionConfig.getMemberLimit();
	}

	/**
	 * 检查帮派成员数是否达到限制
	 * 
	 * @param union
	 *            帮派对象
	 * @return 返回布尔值，true表示已经达到最大限制，false表示还未达到限制人数
	 */
	public boolean checkUnionMemberLimit(Union union, int size) {
		UnionConfig unionConfig = getUnionConfigByLevel(union.getLevel());
		return (union.getMembers().size() + size) > unionConfig.getMemberLimit();
	}

	/**
	 * 清空帮派申请邀请记录
	 * 
	 * @param player
	 */
	public void clearApplyAndInvite(Player player) {
		List<Integer> unionIds = new ArrayList<Integer>();

		if (player.getDataInfo().getApplyUnionSize() > 0) {
			unionIds.addAll(player.getDataInfo().getApplyUnions());

			for (Integer id : unionIds) {
				Union u = Context.getUnionServer().getUnionById(id);
				if (u != null) {
					Map<Long, Integer> applyMap = DataSerialize.getInstance().getApplyMember().get(id);
					if (!BlankUtils.isBlank(applyMap)) {
						applyMap.remove(player.getPlayerId());
						DataSerialize.getInstance().commitSync();
					}
					u.removeInviteMember(player.getPlayerId());
				}
			}
		}

		player.getDataInfo().clearApplyUnion();
	}

	/**
	 * 移除帮会称号
	 */
	public void removeUnionTitle(long playerId) {
		List<Title> titles = Context.getCacheCenter().getTitles(Constants.titleUnionRanking);
		for (Title title : titles) {
			Context.getGeneralServer().removeTitle(playerId, title.getId());
		}
	}

	/**
	 * 添加帮派称号
	 */
	public void addUnionTitle(long abdicateId, long accedeId) {
		Player leader = Context.getPlayerServer().getByPlayerId(abdicateId);
		List<Title> titles = Context.getCacheCenter().getTitles(Constants.titleUnionRanking);
		for (Title title : titles) {
			if (Context.getGeneralServer().hasTitle(leader.getPlayerId(), title.getId())) {
				Context.getGeneralServer().addTitle(accedeId, title.getId());
				break;
			}
		}
	}
}
